﻿/*
	Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef Animate_h__
#define Animate_h__

#include "ActionInterval.h"
#include "IActableObject.h"

#include <vector>

namespace SkyEngine2d
{
	class SpriteFrame;
	
	
	/*!
	 \brief 动画帧
	 \details
	*/
	class SGE_API AnimationFrame
	{
		FRIEND_SMART_PTR(AnimationFrame)
	public:
		//! 创建一个动画帧 
		/*!
		\param const SpriteFrameSharedPtr & sf 精灵帧
		\param float dealy 动画的延迟 单位 秒
		\return AnimationFrameSharedPtr 
		*/
		static AnimationFrameSharedPtr create(const SpriteFrameSharedPtr & sf, float dealy);
		
		//! 析构
		~AnimationFrame();
		
		//! 获取精灵帧
		/*!
		\return std::shared_ptr<SpriteFrame>  
		*/
		std::shared_ptr<SpriteFrame> getSpriteFrame()const { return m_spriteFrame; }
		
		//! 获取这一帧的延迟
		/*!
		\return float 
		*/
		float getDealy()const;
	
	protected:
		//!构建
		AnimationFrame();
		//!初始化
		bool init(const std::shared_ptr<SpriteFrame> & sprite_frame, float dealy);
	private:
		std::shared_ptr<SpriteFrame>  m_spriteFrame; /*!< 对应的精灵帧. */
		float    m_dealy;	  /*!< 这帧动画的执行延迟 */
	};
	
	
	/*!
	 \brief 帧动画
	 \details
	*/
	class SGE_API Animation
	{
		FRIEND_SMART_PTR(Animation)
	public:
		//! 创建动画
		/*!
		\return AnimationSharedPtr 
		*/
		static AnimationSharedPtr create();
		
		//! 创建动画
		/*!
		\param const std::vector<AnimationFrameSharedPtr> & frames 动画帧数组
		\param int times 播放的次数 如果为 \a -1 则代表动画一直执行
		\return AnimationSharedPtr  
		*/
		static AnimationSharedPtr create(const std::vector<AnimationFrameSharedPtr> & frames,int times =1);
		
		//! 创建动画
		/*!
		\param const std::vector<SpriteFrameSharedPtr> & frames 精灵帧数组
		\param float delay 每帧的延迟
		\param int times 播放的次数 如果为 \a -1 则代表动画一直执行
		\return AnimationSharedPtr  
		*/
		static AnimationSharedPtr create(const std::vector<SpriteFrameSharedPtr> & frames, float delay = 0.0f, int times = 1);
		
		//! 析构
		~Animation();
	
		//! 获取动画帧数组
		/*!
		\return const std::vector<std::shared_ptr<AnimationFrame>>&  
		*/
		const std::vector<AnimationFrameSharedPtr>& getAnimationFrams()const;	
		
		//! 该动画播放多少次
		/*!
		\return int  
		*/
		int getDisplayTimes()const;
	
		//! 设置播放的次数
		/*!
		\param int times  播放的次数  -1 为 一直播放
		\return void 
		*/
		void setDisplayTimes(int times);
	
		//! 该完整动画播放一次需要的时间
		/*!
		\return float 
		*/
		float  getDisplayOnceDuration()const;
		
		//! 动画的帧数
		/*!
		\return int  
		*/
		int  getFrameCount() const;
	
		//! 对应帧的延时
		/*!
		\param int index 帧的索引 
		\return float  
		*/
		float getFrameDealy(int index)const;
	
		//! 在动画播放完毕 是否回到原始的精灵帧
		/*!
		\return bool 
		*/
		bool  isRestOriginalFrame()const;
	
		//! 设置动画播放完是否回到原始的精灵帧
		/*!
		\param bool rest 是否重置为原始精灵帧
		\return void 
		该属性默认为 \a ture
		*/
		void  setRestOriginalFrame(bool rest);
	
		//! 添加动画帧数组精灵帧
		/*!
		\param const std::vector<AnimationFrameSharedPtr> & frames 动画帧数组
		\return void 
		*/
		void addFrames(const std::vector<AnimationFrameSharedPtr> & frames);
		
		//! 添加动画帧
		/*!
		\param const AnimationFrameSharedPtr & frame 
		\return void  
		*/
		void addFrame(const AnimationFrameSharedPtr & frame);
	
	protected:
		bool init();
		bool initWithAnimationFrame(const std::vector<std::shared_ptr<AnimationFrame>>& frams, int times);
		bool initWithSpriteFrame(const std::vector<std::shared_ptr<SpriteFrame>> & frames, float delay, int times);
		Animation();
	private:
	
		int		m_framesCount;			//动画的帧数
		float	m_duration;				//完整播放一次动画需要的时间
		bool	m_isRestOriginalFrame;	//动画播放完毕  是否从置的原始的帧  
		int		m_displayTimes;			//这个动画播放多少次  
	
		std::vector<std::shared_ptr<AnimationFrame>> m_frames;
	 };
	
	
	 /*!
	  \brief 执行帧动画的动作
	  \details
	 */
	class SGE_API Animate
		:public ActionInterval
	{
		FRIEND_SMART_PTR(Animate)
	public:
		//! 创建一个动画动作
		/*!
		\param const std::shared_ptr<Animation> & animation 动画
		\return std::unique_ptr<Animate>  
		*/
		static AnimateSharedPtr create(const std::shared_ptr<Animation> & animation);
		
		//! 将动画动作的指针转为 基类 的指针
		/*!
		\param AnimateUniquePtr p 
		\return ActionUniquePtr  
		*/
		ActionSharedPtr convertToActionUptr();
	
		//! 析构
		virtual ~Animate();
	
		//! 获取动画的引用
		/*!
		\return const AnimationSharedPtr &  
		*/
		const AnimationSharedPtr & getAnimation()const;
	
		//! 获取帧的索引
		/*!
		\return int  
		*/
		int  getCurrentFrameIndex();
	
		//! 停止动画
		/*!
		\return void  
		*/
		virtual void stop() override;
	
		//! 开始动画
		/*!
		\param const std::shared_ptr<IActableObject>& target 
		\return bool  
		*/
		virtual bool startWithTarget(IActableObject* target) override;
	
	protected:
	
		Animate();
		bool initWithAnimation(const std::shared_ptr<Animation> & animation);
		virtual void update(float ratio)override;
		virtual bool setActionTarget(IActableObject* obj) override;
		void setAnimation(const std::shared_ptr<Animation> & animation);
	protected:
		IAnimatableObject*						m_currentTarget;    //当前的动画目标
		std::vector<float>						m_timePerFrame;		//每帧的时间      
		int										m_nextFrameIndex;  
		std::shared_ptr<SpriteFrame>			m_origFrame;  
		int										m_currentFrameIndex;
		int										m_displayedCount;    //已经执行的循环次数
		std::shared_ptr<Animation>				m_animation;
	};
}

#endif // Animate_h__
